package com.nulldev.util.promise;

import java.net.URL;

import com.nulldev.util.promise.noresult.NoResultPromise;
import com.nulldev.util.promise.url.URLPromise;
import com.nulldev.util.threading.fastES.LtqExecutor;
import com.nulldev.util.threading.legacy.ThreadExecutor;
import com.nulldev.util.threading.v2.ThreadExecution;
import com.nulldev.util.threading.v2.ThreadManager;
import com.nulldev.util.threading.v2.ThreadMode;
import com.nulldev.util.threading.v2.ThreadPriority;
import com.nulldev.util.threading.v2.nThread;
import com.nulldev.util.threading.v3.ThreadDispatcher;
import com.nulldev.util.uri.URIUtil;

public class Promiser {
	
	private static final ThreadDispatcher tm = new ThreadDispatcher(new LtqExecutor(64));
	
	public static <T> void promise(final Promise<T> promise) {
		tm.addTask(new nThread(new Runnable() {
			
			@Override
			public void run() {
				try {
					final T result = promise.run();
					promise.result(result);
				}catch (final Throwable e) {
					promise.error(e);
				}
			}
		}, "$promise", ThreadPriority.NORMAL, ThreadExecution.LOOPED, ThreadMode.NORMAL).toWorker());
	}
	
	public static void promise(final NoResultPromise promise) {
		tm.addTask(new nThread(new Runnable() {
			
			@Override
			public void run() {
				try {
					promise.run();
				}catch (final Throwable e) {
					promise.error(e);
				}
			}
		}, "$promise", ThreadPriority.NORMAL, ThreadExecution.LOOPED, ThreadMode.NORMAL).toWorker());
	}
	
	public static void promiseToThreadExecutor(final NoResultPromise promise) {
		ThreadExecutor.execute(new Runnable() {
			
			@Override
			public void run() {
				try {
					promise.run();
				}catch (final Throwable e) {
					promise.error(e);
				}
			}
		});
	}
	
	public static void promise(final URL url, final URLPromise promise) {
		tm.addTask(new nThread(new Runnable() {
			
			@Override
			public void run() {
				try {
					final String result = URIUtil.downloadPage(url);
					promise.result(result);
				}catch (final Throwable e) {
					promise.error(e);
				}
			}
		}, "$promise", ThreadPriority.NORMAL, ThreadExecution.LOOPED, ThreadMode.NORMAL).toWorker());
	}
}
